import React, { useEffect, useRef, useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Alert, TextInput, FlatList } from 'react-native';
import { pick, DocumentPickerResponse } from '@react-native-documents/picker';
import AsyncStorage from '@react-native-async-storage/async-storage';
import RNFS from 'react-native-fs';
import { md5 } from 'js-md5';
import {
  speedTest,
  checkFileExists,
  getFileList as getFileListAPI,
  uploadFile as uploadFileAPI,
  mergeFile as mergeFileAPI,
  FileInfo
} from '../../ulits/instance';

interface ChunkInfo {
  index: number;
  start: number;
  end: number;
  size: number;
}

export default function FileUpload() {
  const fileRef = useRef<DocumentPickerResponse | null>(null);
  const [networkSpeed, setNetworkSpeed] = useState(0); // 网络速度(Mbps)
  const [currentChunkSize, setCurrentChunkSize] = useState<number | null>(null); // 当前分片大小(MB)
  const [statusMessage, setStatusMessage] = useState(''); // 状态消息
  const [title, setTitle] = useState(''); // 文件标题
  const [progress, setProgress] = useState(0); // 上传进度
  const [fileList, setFileList] = useState<FileInfo[]>([]); // 文件列表
  const parsedData = AsyncStorage.getItem('userData');
  const [userId, setUserId] = useState<string | null>(null); // 存储 _id

  // 获取文件列表
  const getFileList = async () => {
    try {
      const response = await getFileListAPI();
      if (response.code === 200) {
        setFileList(response.data);
      }
    } catch (error) {
      console.error('获取文件列表失败:', error);
      setStatusMessage('获取文件列表失败');
    }
  };

  useEffect(() => {
    getFileList();
  }, []);

  // 根据文件大小计算分片大小
  const getFileSizeChunkSize = (fileSize: number) => {
    const sizeInMB = fileSize / (1024 * 1024); // 转换为MB
    if (sizeInMB <= 100) return 2 * 1024 * 1024; // <100MB用1MB分片
    if (sizeInMB <= 1024) return 4 * 1024 * 1024; // 100MB-1GB用2MB分片
    return 10 * 1024 * 1024; // >1GB用5MB分片
  };

  // 根据网络速度调整分片大小
  const getNetworkChunkSize = (speed: number) => {
    if (speed < 20) return 256 * 1024; // <20Mbps用256KB
    if (speed < 30) return 512 * 1024; // 20-30Mbps用512KB
    if (speed < 40) return 1 * 1024 * 1024; // 30-40Mbps用1MB
    return 2 * 1024 * 1024; // >40Mbps用2MB
  };

  // 测量网络速度
  const measureNetworkSpeed = async () => {
    try {
      const startTime = Date.now();
      const blob = await speedTest();
      const duration = (Date.now() - startTime) / 1000;
      const speed = (blob.size * 8 / duration) / 1024 / 1024;
      setNetworkSpeed(Number(speed.toFixed(2)));
      return speed;
    } catch (error) {
      console.error('测速失败:', error);
      setNetworkSpeed(0);
      setCurrentChunkSize(256 * 1024 / (1024 * 1024));
      setStatusMessage('网络测速失败');
      return 0;
    }
  };

  useEffect(() => {
    measureNetworkSpeed();
    const timer = setInterval(measureNetworkSpeed, 3000);
    return () => clearInterval(timer);
  }, []);

  // 选择文件
  const pickFile = async () => {
    setStatusMessage('正在选择文件...');
    try {
      const result = await pick({
        type: ['image/*', 'video/*'],
      });
      if (result && result.length > 0) {
        fileRef.current = result[0];
        setStatusMessage(`已选择: ${fileRef.current.name}`);
        setProgress(0); // Reset progress when selecting a new file

        // 检查断点续传记录
        const chunkStatusKey = `${fileRef.current.name}-chunkStatus`;
        const chunkStatusStr = await AsyncStorage.getItem(chunkStatusKey);
        if (chunkStatusStr) {
          setStatusMessage(`检测到断点记录，可从已上传分片继续`);
        }
      } else {
        setStatusMessage('未选择任何文件');
      }
    } catch (err: any) {
      if (err.message.includes('cancel')) {
        setStatusMessage('用户取消了选择');
      } else {
        setStatusMessage('选择文件失败，请检查存储权限');
        Alert.alert('选择文件失败', '请确保已授予存储权限', [{ text: '确定' }]);
      }
    }
  };

  // 计算文件MD5
  const getFileMD5 = async (fileUri: string): Promise<string> => {
    const fileData = await RNFS.readFile(fileUri, 'base64');
    return md5(fileData);
  };

  // 清空断点续传记录
  const clearBreakpointResume = async () => {
    const file = fileRef.current;
    if (!file) {
      setStatusMessage('请先选择文件');
      return;
    }

    try {
      const chunkStatusKey = `${file.name}-chunkStatus`;
      await AsyncStorage.removeItem(chunkStatusKey);
      setProgress(0);
      setStatusMessage('已清空断点续传记录');
    } catch (error) {
      setStatusMessage('清空断点续传记录失败');
      console.error('清空断点续传失败:', error);
    }
  };

  // 上传文件
  const upload = async () => {
    const file = fileRef.current;
    if (!file) {
      setStatusMessage('请先选择文件');
      return;
    }
    if (!title.trim()) {
      setStatusMessage('请输入标题');
      return;
    }
    if (!file.size) {
      setStatusMessage('无法获取文件大小');
      return;
    }

    setStatusMessage('正在校验秒传...');
    let fileMD5 = '';
    try {
      fileMD5 = await getFileMD5(file.uri);
    } catch (e) {
      setStatusMessage('MD5计算失败，转为普通上传');
    }

    // 秒传校验
    try {
      const exists = await checkFileExists(fileMD5);
      if (exists) {
        setStatusMessage('文件已存在，秒传成功！');
        setProgress(100);
        setCurrentChunkSize(null);
        setTitle('');
        await AsyncStorage.removeItem(`${file.name}-chunkStatus`);
        getFileList();
        return;
      }
    } catch (e) {
      setStatusMessage('秒传校验失败，转为普通上传');
    }

    setStatusMessage('准备上传...');
    const currentSpeed = await measureNetworkSpeed();
    const chunkSize = getNetworkChunkSize(currentSpeed);
    const totalChunks = Math.ceil(file.size / chunkSize);
    let completedChunks = 0;
    const chunkStatusKey = `${file.name}-chunkStatus`;

    // 读取上传进度
    const chunkStatusStr = await AsyncStorage.getItem(chunkStatusKey);
    let chunkStatus: Record<number, boolean> = chunkStatusStr ? JSON.parse(chunkStatusStr) : {};

    // 准备分片
    const chunks: ChunkInfo[] = [];
    for (let i = 0; i < totalChunks; i++) {
      const start = i * chunkSize;
      const end = Math.min(start + chunkSize, file.size);
      chunks.push({ index: i, start, end, size: end - start });
    }

    // 过滤未上传的分片
    const chunksToUpload = chunks.filter(chunk => !chunkStatus[chunk.index]);
    completedChunks = Object.values(chunkStatus).filter(Boolean).length;
    setProgress((completedChunks / totalChunks) * 100);

    // 上传分片
    const uploadChunk = async (chunk: ChunkInfo) => {
      const chunkSizeInMB = chunk.size / (1024 * 1024);
      setCurrentChunkSize(chunkSizeInMB);
      setStatusMessage(`上传第 ${chunk.index + 1}/${totalChunks} 块 (${chunkSizeInMB.toFixed(2)}MB)`);

      const formData = new FormData();
      formData.append('file', {
        uri: file.uri,
        type: file.type || 'application/octet-stream',
        name: file.name,
      });
      formData.append('filename', file.name);
      formData.append('totalChunks', totalChunks.toString());
      formData.append('currentChunk', chunk.index.toString());
      formData.append('title', title);

      try {
        await uploadFileAPI(formData);
        chunkStatus[chunk.index] = true;
        await AsyncStorage.setItem(chunkStatusKey, JSON.stringify(chunkStatus));
        completedChunks++;
        const currentProgress = (completedChunks / totalChunks) * 100;
        setProgress(currentProgress);
        setStatusMessage(`上传进度: ${currentProgress.toFixed(2)}%`);
      } catch (error) {
        throw new Error(`分片 ${chunk.index} 上传失败`);
      }
    };

    // 并发控制(4个并发)
    const concurrency = 4;
    const runBatches = async (chunks: ChunkInfo[], batchSize: number) => {
      for (let i = 0; i < chunks.length; i += batchSize) {
        const batch = chunks.slice(i, i + batchSize);
        await Promise.all(batch.map(uploadChunk));
      }
    };

    try {
      await runBatches(chunksToUpload, concurrency);

      // 合并分片
      await mergeFileAPI({
        filename: file.name,
        totalChunks: totalChunks,
        title: title,
        fileHash: fileMD5,
        idd: userId
      });

      setStatusMessage('文件上传并合并成功');
      setCurrentChunkSize(null);
      setTitle('');
      setProgress(100);
      await AsyncStorage.removeItem(chunkStatusKey);
      getFileList();
    } catch (error) {
      setStatusMessage('上传失败: ' + error.message);
      setCurrentChunkSize(null);
    }
  };
  const getUserData = async () => {
    try {
      const userDataString = await AsyncStorage.getItem('userData');
      if (userDataString) {
        const parsedData = JSON.parse(userDataString);
        const _id = parsedData._id;
        setUserId(_id)
        return _id;
      } else {
        console.log('未找到用户数据');
        return null;
      }
    } catch (error) {
      console.error('获取用户数据出错:', error);
      return null;
    }
  };

  // 在需要的地方调用此函数，例如 useEffect 或 upload
  useEffect(() => {
    getUserData();
  }, []);

  const asd = () => {
    console.log(userId,'1');
  };

  // 渲染文件项
  const renderFileItem = ({ item }: { item: FileInfo }) => (
    <View style={styles.fileItem}>
      <Text style={styles.fileTitle}>{item.title}</Text>
      <Text style={styles.fileDate}>
        {new Date(item.uploadDate).toLocaleString()}
      </Text>
    </View>
  );

  return (
    <View style={styles.container}>
      <Text style={styles.title}>文件上传</Text>

      <TextInput
        style={styles.input}
        placeholder="输入文件标题"
        value={title}
        onChangeText={setTitle}
        placeholderTextColor="#999"
      />

      <TouchableOpacity style={styles.button} onPress={pickFile}>
        <Text style={styles.buttonText}>选择文件</Text>
      </TouchableOpacity>

      <TouchableOpacity
        style={[styles.button, styles.uploadButton]}
        onPress={upload}
      >
        <Text style={styles.buttonText}>开始上传</Text>
      </TouchableOpacity>

      <TouchableOpacity
        style={[styles.button, styles.clearButton]}
        onPress={clearBreakpointResume}
      >
        <Text style={styles.buttonText}>清空断点续传</Text>
      </TouchableOpacity>

      <TouchableOpacity
        style={[styles.button, styles.uploadButton]}
        onPress={asd}
      >
        <Text style={styles.buttonText}>开始</Text>
      </TouchableOpacity>

      <View style={styles.progressContainer}>
        <Text>进度: {progress.toFixed(1)}%</Text>
        <View style={styles.progressBar}>
          <View style={[styles.progressFill, { width: `${progress}%` }]} />
        </View>
      </View>

      <View style={styles.statusBox}>
        <Text>网络速度: {networkSpeed.toFixed(2)} Mbps</Text>
        {currentChunkSize && (
          <Text>当前分片: {currentChunkSize.toFixed(2)} MB</Text>
        )}
        <Text style={styles.statusText}>{statusMessage}</Text>
      </View>

    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
    textAlign: 'center',
    color: '#333',
  },
  input: {
    height: 50,
    borderColor: '#ddd',
    borderWidth: 1,
    borderRadius: 8,
    paddingHorizontal: 15,
    marginBottom: 15,
    backgroundColor: '#fff',
  },
  button: {
    backgroundColor: '#4a90e2',
    padding: 15,
    borderRadius: 8,
    alignItems: 'center',
    marginBottom: 15,
  },
  uploadButton: {
    backgroundColor: '#2ecc71',
  },
  clearButton: {
    backgroundColor: '#e74c3c',
  },
  buttonText: {
    color: '#fff',
    fontWeight: 'bold',
    fontSize: 16,
  },
  progressContainer: {
    marginBottom: 15,
  },
  progressBar: {
    height: 10,
    backgroundColor: '#ecf0f1',
    borderRadius: 5,
    marginTop: 5,
    overflow: 'hidden',
  },
  progressFill: {
    height: '100%',
    backgroundColor: '#3498db',
  },
  statusBox: {
    padding: 15,
    backgroundColor: '#fff',
    borderRadius: 8,
    marginBottom: 15,
    borderWidth: 1,
    borderColor: '#eee',
  },
  statusText: {
    marginTop: 10,
    color: '#e74c3c',
    fontWeight: '500',
  },
  list: {
    flex: 1,
  },
  fileItem: {
    backgroundColor: '#fff',
    padding: 15,
    borderRadius: 8,
    marginBottom: 10,
    borderWidth: 1,
    borderColor: '#eee',
  },
  fileTitle: {
    fontWeight: 'bold',
    marginBottom: 5,
  },
  fileDate: {
    color: '#7f8c8d',
    fontSize: 12,
  },
});